package com.huhao.wshare.service.impl;

import com.huhao.wshare.dto.User.Request.UserLoginRequest;
import com.huhao.wshare.dto.User.Request.UserPasswordUpdateRequest;
import com.huhao.wshare.dto.User.Request.UserRegisterRequest;
import com.huhao.wshare.dto.User.Request.UserUpdateRequest;
import com.huhao.wshare.dto.User.Response.LoginResponse;
import com.huhao.wshare.dto.User.Response.UserProfileResponse;
import com.huhao.wshare.dto.User.Response.UserSearchResponse;
import com.huhao.wshare.entity.User;
import com.huhao.wshare.repository.FriendsRepository;
import com.huhao.wshare.repository.UserRepository;
import com.huhao.wshare.service.UserService;
import com.huhao.wshare.service.VerifyCodeService;
import com.huhao.wshare.service.constant.VerificationCodeType; // 新增导入
import com.huhao.wshare.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;
    private final FriendsRepository friendsRepository;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;
    private final VerifyCodeService verifyCodeService;

    @Override
    @Transactional
    public User register(UserRegisterRequest request, String verificationCode) {
        // 验证验证码，明确指定类型为注册
        if (!verifyCodeService.verifyCode(request.getEmail(), verificationCode, VerificationCodeType.REGISTRATION)) {
            throw new IllegalArgumentException("验证码无效或已过期");
        }

        if (userRepository.existsByEmail(request.getEmail())) {
            throw new IllegalArgumentException("错误：邮箱已被注册！");
        }
        if (userRepository.existsByPhone(request.getPhone())) {
            throw new IllegalArgumentException("错误：手机号已被注册！");
        }
        if (userRepository.existsByAccount(request.getAccount())) {
            throw new IllegalArgumentException("错误：账号已被注册！");
        }

        User user = new User();
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setAccount(request.getAccount());
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setGender(request.getGender());
        user.setIsLogin(0);

        return userRepository.save(user);
    }

    @Override
    @Transactional
    public LoginResponse login(UserLoginRequest request) {
        Optional<User> userOptional = userRepository.findByEmailOrPhoneOrAccount(
                request.getIdentifier(), request.getIdentifier(), request.getIdentifier());

        User user = userOptional.orElseThrow(() -> new IllegalArgumentException("错误：用户不存在！"));

        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new IllegalArgumentException("错误：密码不正确！");
        }
        if (user.getIsLogin() != null && user.getIsLogin() == 1) {
            throw new IllegalArgumentException("该用户已经登陆，请勿重复登录");
        }

        user.setIsLogin(1);
        userRepository.save(user);

        String token = jwtUtil.generateToken(user.getAccount());

        return new LoginResponse(HttpStatus.OK.value(), token, user.getId(), user.getUsername(), "登录成功！");
    }

    @Override
    @Transactional
    public void logout(String account) {
        userRepository.findByAccount(account).ifPresent(user -> {
            user.setIsLogin(0);
            userRepository.save(user);
        });
    }



    @Override
    public UserProfileResponse getUserProfile(Long userId) throws IllegalArgumentException {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("错误：用户不存在！"));
        return UserProfileResponse.fromUser(user);
    }

    @Override
    @Transactional
    public User updateUserProfile(Long currentUserId, UserUpdateRequest request) throws IllegalArgumentException {
        User user = userRepository.findById(currentUserId)
                .orElseThrow(() -> new IllegalArgumentException("错误：用户不存在！"));

        // --- 修改点：重构邮箱和手机号的重复性校验逻辑 ---

        // 检查并更新邮箱
        if (request.getEmail() != null && !request.getEmail().isEmpty()) {
            // 检查新邮箱是否已被其他用户占用
            Optional<User> existingUserByEmail = userRepository.findByEmail(request.getEmail());
            if (existingUserByEmail.isPresent() && !existingUserByEmail.get().getId().equals(currentUserId)) {
                throw new IllegalArgumentException("错误：该邮箱已被其他用户注册！");
            }
            // 如果邮箱未被占用，或者就是当前用户自己的邮箱，则更新
            user.setEmail(request.getEmail());
        }

        // 检查并更新手机号
        if (request.getPhone() != null && !request.getPhone().isEmpty()) {
            // 检查新手机号是否已被其他用户占用
            Optional<User> existingUserByPhone = userRepository.findByPhone(request.getPhone());
            if (existingUserByPhone.isPresent() && !existingUserByPhone.get().getId().equals(currentUserId)) {
                throw new IllegalArgumentException("错误：该手机号已被其他用户注册！");
            }
            // 如果手机号未被占用，或者就是当前用户自己的手机号，则更新
            user.setPhone(request.getPhone());
        }

        // --- 修改点结束 ---

        if (request.getUsername() != null && !request.getUsername().isEmpty()) {
            user.setUsername(request.getUsername());
        }
        if (request.getSigns() != null) {
            user.setSigns(request.getSigns());
        }
        if (request.getGender() != null && !request.getGender().isEmpty()) {
            user.setGender(request.getGender());
        }
        if (request.getAvatar() != null) {
            user.setAvatar(request.getAvatar());
        }
        if (request.getBkImg() != null) {
            user.setBkImg(request.getBkImg());
        }
        return userRepository.save(user);
    }

    @Override
    @Transactional
    public void updatePassword(Long currentUserId, UserPasswordUpdateRequest request) throws IllegalArgumentException {
        User user = userRepository.findById(currentUserId)
                .orElseThrow(() -> new IllegalArgumentException("错误：用户不存在！"));

        // 1. 验证邮箱验证码，明确指定类型为密码重置
        if (!verifyCodeService.verifyCode(user.getEmail(), request.getVerificationCode(), VerificationCodeType.PASSWORD_RESET)) {
            throw new IllegalArgumentException("验证码无效或已过期");
        }

        // 2. 更新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        userRepository.save(user);
    }

    /**
     * 【修改】根据用户的唯一标识 (邮箱、手机号或账号) 查询用户，并检查好友关系
     * @param currentUserId 当前登录用户的ID
     * @param identifier 用户的邮箱、手机号或账号
     * @return 包含用户ID和好友关系状态的 DTO
     * @throws IllegalArgumentException 如果用户不存在或查询自己
     */
    @Override
    @Transactional(readOnly = true)
    public UserSearchResponse findUserByIdentifier(Long currentUserId, String identifier) throws IllegalArgumentException {
        // 1. 根据标识符查找目标用户
        User targetUser = userRepository.findByEmailOrPhoneOrAccount(identifier, identifier, identifier)
                .orElseThrow(() -> new IllegalArgumentException("错误：用户不存在！"));
        Long targetUserId = targetUser.getId();

        // 2. 不允许用户查询自己
        if (currentUserId.equals(targetUserId)) {
            throw new IllegalArgumentException("不能查询自己");
        }

        // 3. 检查好友关系 (status=1 表示已是好友)
        // 好友关系是双向的，所以需要检查 (A, B) 和 (B, A) 两种情况
        final int FRIEND_STATUS_ACCEPTED = 1;
        boolean isFriend = friendsRepository.existsByUser_IdAndFriend_IdAndStatus(currentUserId, targetUserId, FRIEND_STATUS_ACCEPTED) ||
                friendsRepository.existsByUser_IdAndFriend_IdAndStatus(targetUserId, currentUserId, FRIEND_STATUS_ACCEPTED);

        // 4. 构建并返回结果
        return UserSearchResponse.builder()
                .userId(targetUserId)
                .isFriend(isFriend)
                .build();
    }
}
